//
//  PMSimpleMotor.m
//  PezMonkey
//
//  Created by Spence DiNicolantonio on 12/23/09.
//  Copyright 2009 Necrosoft. All rights reserved.
//

/**
 * A subclass of PMConstraint for representing simple motors. PMSimpleMotors are
 * used to maintain a relative angular velocity between two rigid bodies. By making 
 * one of the rigid bodies static, you can maintain constant angular motion in
 * the opposite body. 
 * 
 * It is usually desirable to set a maximum force (torque in this case) for simple
 * motors. Otherwise, the relative rate could approach infinity causing both rigid
 * bodies to rotate with near-infinite velocity. 
 */

#import "PMSimpleMotor.h"
#import "PMBody.h"


@implementation PMSimpleMotor

#pragma mark -
#pragma mark Init

/**
 * Returns a PMSimpleMotor object initialized to rotate two given rigid bodies
 * at a given relative rate. 
 */
- (id)initWithBodyA:(PMBody *)aBody bodyB:(PMBody *)otherBody rate:(PMFloat)rate {
	if (![super init])
		return nil;
	
	// allocate and initialize cpConstraint
	constraint = cpSimpleMotorNew(aBody.cpBody, otherBody.cpBody, rate);
	
	// set body references
	self.bodyA = aBody;
	self.bodyB = otherBody;
	
	// reference this PMConstraint object with cpConstraint's data pointer
	// this is for internal use
	constraint->data = self;
	
	return self;
}

 
#pragma mark Convenience
 
/**
 * Creates and returns a PMSimpleMotor object initialized to rotate two given 
 * rigid bodies at a given relative rate. 
 */
+ (PMSimpleMotor *)simpleMotorWithBodyA:(PMBody *)aBody bodyB:(PMBody *)otherBody rate:(PMFloat)rate {
	return [[[PMSimpleMotor alloc] initWithBodyA:aBody 
										   bodyB:otherBody 
											rate:rate] autorelease];
}


#pragma mark -
#pragma mark Getters

/**
 * Returns relative angular velocity maintained by the receiver for the receiver's
 * rigid bodies.
 */
- (PMFloat)rate {
	return cpSimpleMotorGetRate(constraint);
}
	

#pragma mark -
#pragma mark Setters

/**
 * Sets the maintained relative angular velocity for the receiver's rigid bodies
 * to a given value.
 */
- (void)setRate:(PMFloat)rate {
	cpSimpleMotorSetRate(constraint, rate);
}

@end
